package com.ruoyi.common.wx;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.security.cert.X509Certificate;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;

import com.github.wxpay.sdk.WXPayConfig;
import com.ijpay.core.IJPayHttpResponse;
import com.ijpay.core.enums.RequestMethod;
import com.ijpay.core.kit.PayKit;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.core.utils.DateTimeZoneUtil;
import com.ijpay.wxpay.WxPayApi;
import com.ijpay.wxpay.enums.WxApiType;
import com.ijpay.wxpay.enums.WxDomain;
import com.ijpay.wxpay.model.v3.Amount;
import com.ijpay.wxpay.model.v3.UnifiedOrderModel;
import com.ruoyi.common.utils.QrCode;

import cn.hutool.core.io.FileUtil;
import cn.hutool.json.JSONUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
/**
 *	微信支付配置类
 * @author liuz
 */
@Slf4j
@Component
@Data
public class WxConfig implements WXPayConfig{

	@Value("${wxpay.config.appId}")
	private String appId;

	@Value("${wxpay.config.mchId}")
	private String mchId;

	@Value("${wxpay.config.key}")
	private String key;
	@Value("${wxpay.config.keyPath}")
	private String keyPath;

	@Value("${wxpay.config.notifyUrl}")
	private String notifyUrl;
	
	@Value("${wxpay.config.CertPath}")
	private String certPath;

	@Value("${wxpay.config.PlatformCertPath}")
	private String platformCertPath;
	
	@Value("${wxpay.config.ApiKey3}")
	private String apiKey3;
	

	/**
	 * 证书
	 */
	public InputStream certStream;

	/**
	 * HTTP(S) 连接超时时间，单位毫秒
	 */
	private int httpConnectTimeoutMs = 8000;

	/**
	 * HTTP(S) 读数据超时时间，单位毫秒
	 */
	private int httpReadTimeoutMs = 10000;

	@Override
	public String getAppID() {
		return appId;
	}

	@Override
	public String getMchID() {
		return mchId;
	}

	public static void main(String[] args) throws Exception{
		WxConfig config = new WxConfig();
		config.getCertStream();
		System.out.println(config.getCertStream());
	}

	public InputStream getCertStream() {
		//工程内部读取
		ClassPathResource classPathResource = new ClassPathResource("wxpay/apiclient_cert.p12");
		try{
			return classPathResource.getInputStream();
		}catch (IOException e){
			return null;
		}
	}

	@Override
	public int getHttpConnectTimeoutMs() {
		return httpConnectTimeoutMs;
	}

	@Override
	public int getHttpReadTimeoutMs() {
		return httpReadTimeoutMs;
	}

	@Override
	public String getKey() {
		return key;
	}

	public String getNotifyUrl() {
		return notifyUrl;
	}


	/**
	 * 元转换成分
	 * 微信交易单位为分
	 */
	private String castToCent(String amount) {
		if (amount == null) {
			return "";
		}
		return String.valueOf(BigDecimal.valueOf(Double.valueOf(amount) * 100).intValue());
	}

	/**
	 * 	微信下单
	 * @param orderNo
	 * @param amount
	 * @param remark
	 * @return
	 */
	public String getQrCode(String orderNo,String amount,String remark) {
		String payPath = "";
		try {
			String timeExpire = DateTimeZoneUtil.dateToTimeZone(System.currentTimeMillis() + 1000 * 60 * 60);//支付有效时间
			UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel()
					.setAppid(appId)
					.setMchid(mchId)
					.setDescription(remark)
					.setOut_trade_no(orderNo)
					.setTime_expire(timeExpire)
					.setNotify_url(notifyUrl)
					.setAmount(new Amount().setTotal(Integer.valueOf(castToCent(amount))));

			 IJPayHttpResponse response = WxPayApi.v3(
	                    RequestMethod.POST,
	                    WxDomain.CHINA.toString(),
	                    WxApiType.NATIVE_PAY.toString(),
	                    mchId,
	                    getSerialNumber(),
	                    null,
	                    keyPath,
	                    JSONUtil.toJsonStr(unifiedOrderModel)
	            );
			// 根据证书序列号查询对应的证书来验证签名结果
			boolean verifySignature = WxPayKit.verifySignature(response, platformCertPath);
			log.info("verifySignature:{}",verifySignature);
			log.info("response:{}",response.getBody());
			payPath = QrCode.codeCreate(response.getBody());
		} catch (Exception e) {
			e.printStackTrace();
			payPath = "";
		}
		return payPath;
	}

	private String getSerialNumber() {
		// 获取证书序列号
		X509Certificate certificate = PayKit.getCertificate(FileUtil.getInputStream(certPath));
		String serialNo = certificate.getSerialNumber().toString(16).toUpperCase();
		System.out.println("serialNo:" + serialNo);
		return serialNo;
	}
}
